package com.hksj.em.service;

import cn.hutool.core.convert.Convert;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hksj.em.dto.create.CreateOperationRoomDTO;
import com.hksj.em.dto.delete.DeleteOperationRoomDTO;
import com.hksj.em.dto.update.UpdateOperationRoomDTO;
import com.hksj.em.entity.CaregiverTask;
import com.hksj.em.entity.OperationRoom;
import com.hksj.em.mapper.OperationRoomMapper;
import com.hksj.em.query.OperationRoomQuery;
import com.hksj.em.vo.LatestOperationRoomVO;
import com.hksj.em.vo.OperationRoomDataVO;
import com.hksj.em.vo.OperationRoomFromHisVO;
import com.hksj.em.vo.OperationRoomVO;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.ObjectUtils;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author zengke
 * @version 1.0
 * @see OperationRoomService
 * @since 2025/03/25 10:15
 */

@Service
public class OperationRoomService extends ServiceImpl<OperationRoomMapper, OperationRoom> {

    /**
     * 创建手术室信息
     * @param dto 创建手术室信息数据传输对象
     * @return 是否创建成功
     */
    @Transactional
    public String createOperationRoom(CreateOperationRoomDTO dto) {

        //查询数据库中是否存在相同code的手术室
        //查询当前code在数据库中存在的数量
        Integer currentCodeCount = lambdaQuery().eq(OperationRoom::getCode, dto.getCode()).count();

        //当前的code在数据库中已存在
        if (currentCodeCount > 0){
            throw new RuntimeException(String.format("当前的手术间CODE-【%s】已存在,请修改后再重新添加",dto.getCode()));
        }

        //将创建手术室数据传输对象转换为手术室实体
        OperationRoom operationRoom = Convert.convert(OperationRoom.class, dto);

        //获取当前登录人

        //创建手术室信息
        super.save(operationRoom);

        return "添加手术室成功";
    }

    /**
     * 更新手术室信息
     * @param dto 更新手术室数据传输对象
     * @return 是否更新成功
     */
    @Transactional
    public String updateOperationRoom(UpdateOperationRoomDTO dto) {

        //查询当前的手术室信息修改code后在数据库中是否有重复的记录
        Integer codeCount = lambdaQuery().ne(OperationRoom::getId, dto.getId())//除去自身记录的code
                .eq(OperationRoom::getCode, dto.getCode()) //当前修改后的code与数据库中的code进行匹配
                .count();//查询存在数量

        //判断数量是否大于0
        if (codeCount > 0){
            //若大于0则表示其他的记录的code已存在当前修改的code
            throw new RuntimeException(String.format("当前修改的手术室CODE-【%s】已存在,请修改后重新进行编辑",dto.getCode()));
        }

        //将更新手术室数据传输对象转换为手术室实体
        OperationRoom operationRoom = Convert.convert(OperationRoom.class, dto);

        //做更新
        super.updateById(operationRoom);

        return "更新手术室信息成功";
    }

    /**
     * 删除手术室信息
     * @param dto 删除手术室数据传输对象
     * @return 是否删除成功
     */
    @Transactional
    public String deleteOperationRoom(DeleteOperationRoomDTO dto) {

        //通过id查询手术室信息是否存在
        OperationRoom entity = super.getById(dto.getId());

        //判断手术室是否不存在
        if (ObjectUtils.isEmpty(entity)){
            //手术室不存在
            throw new RuntimeException("当前手术室不存在或已删除");
        }

        //删除手术室
        super.removeById(dto.getId());

        return "删除手术室成功";
    }

    /**
     * 分页查询手术室列表
     * @param query 手术室查询对象
     * @return 分页结果
     */
    public IPage<OperationRoomVO> queryOperationRoomListByPaging(OperationRoomQuery query) {

        //创建分页对象
        IPage<OperationRoomVO> page = new Page<>(query.getPageNum(),query.getPageSize());

        //分页查询手术室列表
        List<OperationRoomVO> operationRoomList = baseMapper.queryOperationRoomListByPaging(page,query);

        //将分页结果设置到分页对象中
        page.setRecords(operationRoomList);

        //返回分页结果
        return page;
    }

    /**
     * 动态查询手术室列表
     * @param query 手术室查询对象
     * @return 手术室列表
     */
    public List<OperationRoomVO> queryOperationRoomList(OperationRoomQuery query) {

        //动态查询所有的手术室
        List<OperationRoomVO> operationRoomList = baseMapper.queryOperationRoomListByPaging(null,query);

        //返回手术室列表
        return operationRoomList;
    }

    /**
     * 同步手术室信息
     * @return 是否同步成功
     */
    public String syncOperationRoom() {

        //查询his源的手术室信息
        List<OperationRoomFromHisVO> operationRoomFromHisList = baseMapper.queryOperationRoomFromHisList();

        //查询当前库已有的手术室
        List<OperationRoom> currentOperationRoomList = super.list();

        //插入数据集、his中有而current中没有
        List<OperationRoom> insertTempList = new ArrayList<>();

        //更新数据集、his中有current中也有
        List<OperationRoom> updateTemplList = new ArrayList<>();

        operationRoomFromHisList.forEach(his -> {

            //当前库为空、直接同步his库的数据
            if (currentOperationRoomList == null){
                OperationRoom operationRoom = new OperationRoom();
                operationRoom.setCode(his.getCode());
                operationRoom.setName(his.getName());

                insertTempList.add(operationRoom);
            } else{
                //若当前库不为空且his库中的数据不在当前库中
                if (!currentOperationRoomList.stream().map(OperationRoom::getCode).collect(Collectors.toList()).contains(his.getCode())){
                    OperationRoom operationRoom = new OperationRoom();
                    operationRoom.setCode(his.getCode());
                    operationRoom.setName(his.getName());

                    insertTempList.add(operationRoom);
                } else {

                    //his库的数据在当前库中 此时做更新
                    OperationRoom operationRoom = new OperationRoom();
                    operationRoom.setCode(his.getCode());
                    operationRoom.setName(his.getName());
                    updateTemplList.add(operationRoom);
                }
            }
        });

        //做新增的业务
        if (!ObjectUtils.isEmpty(insertTempList)){
            super.saveBatch(insertTempList);
        }


        //更新的业务
        if (!ObjectUtils.isEmpty(updateTemplList)){
            batchUpdateByCode(updateTemplList);
        }

        return "同步成功";
    }

    public boolean batchUpdateByCode(List<OperationRoom> rooms) {
        return executeBatch(rooms, (sqlSession, entity) -> {
            lambdaUpdate()
                    .eq(OperationRoom::getCode, entity.getCode())
                    .set(entity.getBuildingId() != null, OperationRoom::getBuildingId, entity.getBuildingId())
                    .set(entity.getBuildingName() != null, OperationRoom::getBuildingName, entity.getBuildingName())
                    .set(entity.getFloorId() != null, OperationRoom::getFloorId, entity.getFloorId())
                    .set(entity.getFloorName() != null, OperationRoom::getFloorName, entity.getFloorName())
                    .set(entity.getName() != null, OperationRoom::getName, entity.getName())
                    .set(OperationRoom::getUpdateTime, new Date())
                    .set(entity.getOperatorId() != null, OperationRoom::getOperatorId, entity.getOperatorId())
                    .update();
        });
    }

    /**
     * 分页查询各手术室最新详情
     * @param query 手术室查询对象
     * @return 分页结果
     */
    public IPage<LatestOperationRoomVO> queryLatestOperationRoomInfoListByPaging(OperationRoomQuery query) {

        //创建一个分页对象
        IPage<LatestOperationRoomVO> page = new Page<>(query.getPageNum(),query.getPageSize());

        //分页查询最新手术室信息列表
        List<LatestOperationRoomVO> operationRoomVOList = baseMapper.queryLatestOperationRoomInfoListByPaging(page,query);

        //将查询结果设置到分页对象中
        page.setRecords(operationRoomVOList);

        //返回分页对象
        return page;
    }

    /**
     * 查询手术室数据列表
     * @param roomCode 手术室代码
     * @return 手术室数据列表
     */
    public List<OperationRoomDataVO> queryOperationRoomDataList(String roomCode) {
        return baseMapper.queryOperationRoomDataList(roomCode);
    }
}
